package com.thprojects.myphotomemories.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.net.ConnectivityManager;
import android.util.Log;

import com.thprojects.myphotomemories.model.Contact;
import com.thprojects.myphotomemories.model.Photo;
import com.thprojects.myphotomemories.model.WebPhoto;

import exception.NotOnlineException;

public class WebController {
	private final static String server="http://aleonlinespot.altervista.org";
	private final static String path="/myphotomemories/server.php";
	
	private static String contactListToString(List<Contact> l){
		if (l.size() == 0) return "";
		String res = "";
		res += l.get(0).getDisplayName();
		for (int i=1; i<l.size(); i++){
			res += ", "+l.get(i).getDisplayName();
		}
		return res;
	}
	
	public static boolean isOnline(Context c) {
    	ConnectivityManager cm = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
    	if (cm==null || cm.getActiveNetworkInfo() == null) return false;
    	return cm.getActiveNetworkInfo().isConnectedOrConnecting();
    }
	
	
	public static void publish(Context c, Photo p, String username, String pwd) throws NotOnlineException{
		Log.d("MPM", "WebController: publish");
    	if (!isOnline(c)){
    		if (!isOnline(c)){
    			Log.d("MPM", "WebController: not online");
    			throw new NotOnlineException("You must be connected to the Internet to register");
    		}
		}
    	//get web id for the new photo
    	// Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("action", "publish")); 
        params.add(new BasicNameValuePair("username", username));
        params.add(new BasicNameValuePair("password", pwd));
 
        // getting JSON Object
        try{
        	String jsonCode = RESTClient.post(server+path, params);
			JSONObject json = new JSONObject(jsonCode);
			//now a new photo has been created on server: it has a path and an id, but no image nor details
			int webId = json.getInt("webId");
			DbController dbController = DbController.getDbController(c);
			//save new wid both in photo and database
			dbController.setWebId(p, webId);
			
			//set image details on server
			editPhotoDetails(c, p, username, pwd);
			//send image to server
			editPhotoImage(c, p, username, pwd);
		}
		catch (JSONException je){
			Log.e("MPM", "WebController: "+je.getMessage());
		} catch (IOException e) {
			Log.e("MPM", "WebController: "+e.getMessage());
		}
	}
	
	public static void editPhotoDetails(Context c, Photo p, String username, String pwd) throws NotOnlineException{
		Log.d("MPM", "WebController: editPhotoDetails");
    	if (!isOnline(c)){
    		if (!isOnline(c)){
    			Log.d("MPM", "WebController: not online");
    			throw new NotOnlineException("You must be connected to the Internet to register");
    		}
		}
    	
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("action", "edit_photo_details")); 
        params.add(new BasicNameValuePair("username", username));
        params.add(new BasicNameValuePair("password", pwd));
        params.add(new BasicNameValuePair("id", p.getWebId()+""));
        params.add(new BasicNameValuePair("name", p.getName()));
        params.add(new BasicNameValuePair("caption", p.getCaption()));
        params.add(new BasicNameValuePair("location", p.getLocation()));
        params.add(new BasicNameValuePair("contacts", contactListToString(p.getContacts())));
 
        // getting JSON Object
        try{
        	String jsonCode = RESTClient.post(server+path, params);
			JSONObject json = new JSONObject(jsonCode);
		}
		catch (JSONException je){
			Log.e("MPM", "WebController: "+je.getMessage());
		} catch (IOException e) {
			Log.e("MPM", "WebController: "+e.getMessage());
		}
	}
	
	public static void editPhotoImage(Context c, Photo p, String username, String pwd) throws NotOnlineException{
		Log.d("MPM", "WebController: editPhotoImage");
		if (!isOnline(c)){
			Log.d("MPM", "WebController: not online");
			throw new NotOnlineException("You must be connected to the Internet to publish a photo");
		}
		HttpMultipartClient httpMultipartClient = new HttpMultipartClient(server, path, 80);

		File f = new File(p.getPath());
		FileInputStream fis;
		try {
			fis = new FileInputStream(f);
			httpMultipartClient.addField("action", "edit_photo_image");
			httpMultipartClient.addField("id", p.getWebId()+"");	
			httpMultipartClient.addField("username", username);
			httpMultipartClient.addField("password", pwd);
			httpMultipartClient.addFile(f.getName(), fis, fis.available());
			httpMultipartClient.setRequestMethod("POST");
			httpMultipartClient.send();
		} catch (FileNotFoundException e) {
			GuiController.showError(c, "Can't find the photo to publish");
		} catch (IOException e) {
			GuiController.showError(c, "Can't publish your photo now. Please try again");
		}
		
	}

	public static boolean checkExistentUser(Context context, String name) {
		Log.d("MPM", "WebController: checkExistentUser");
		if (!isOnline(context)){
			Log.d("MPM", "WebController: not online");
			return false;
		}
		
		// Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("action", "exists_user"));
        params.add(new BasicNameValuePair("name", name));
 
        // getting JSON Object
        
        try{
        	String jsonCode = RESTClient.post(server+path, params);
			JSONObject json = new JSONObject(jsonCode);
			int i = json.getInt("exists");
			return i!=0;
		}
		catch (JSONException je){
			Log.e("MPM", "WebController: "+je.getMessage());
			return false;
		} catch (IOException e) {
			Log.e("MPM", "WebController: "+e.getMessage());
			return false;
		}
	}
	
	public static boolean checkCorrectCredentials(Context context, String name, String password) {
		Log.d("MPM", "WebController: checkCorrectCredentials");
		if (!isOnline(context)){
			Log.d("MPM", "WebController: not online");
			return false;
		}
		
		// Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("action", "correct_user"));
        params.add(new BasicNameValuePair("name", name));
        params.add(new BasicNameValuePair("password", password));
 
        // getting JSON Object
        try{
        	String jsonCode = RESTClient.post(server+path, params);
			JSONObject json = new JSONObject(jsonCode);
			int i = json.getInt("correct");
			return i!=0;
		}
		catch (JSONException je){
			Log.e("MPM", "WebController: "+je.getMessage());
			return false;
		} catch (IOException e) {
			Log.e("MPM", "WebController: "+e.getMessage());
			return false;
		}
	}

	
	/**
     * function server-side user registration
     * @param name
     * @param password
     * */
    public static void registerUser(Context c, String name, String password) throws NotOnlineException{
    	Log.d("MPM", "WebController: registerUser");
    	if (!isOnline(c)){
    		if (!isOnline(c)){
    			Log.d("MPM", "WebController: not online");
    			throw new NotOnlineException("You must be connected to the Internet to register");
    		}
		}
    	
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("action", "register")); 
        params.add(new BasicNameValuePair("name", name));
        params.add(new BasicNameValuePair("password", password));
 
        // getting JSON Object
        try{
        	String jsonCode = RESTClient.post(server+path, params);
			JSONObject json = new JSONObject(jsonCode);
		}
		catch (JSONException je){
			Log.e("MPM", "WebController: "+je.getMessage());
		} catch (IOException e) {
			Log.e("MPM", "WebController: "+e.getMessage());
		}
        
    }
    
    /**
     * function server-side user registration
     * @param name
     * @param password
     * */
    public static List<WebPhoto> getPhotos(Context c, String name, String password) throws NotOnlineException{
    	List<WebPhoto> res = new ArrayList<WebPhoto>();
    	
    	Log.d("MPM", "WebController: getPhotos");
    	if (!isOnline(c)){
    		if (!isOnline(c)){
    			Log.d("MPM", "WebController: not online");
    			throw new NotOnlineException("You must be connected to the Internet to get photos");
    		}
		}
    	
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("action", "get_photos")); 
        params.add(new BasicNameValuePair("username", name));
        params.add(new BasicNameValuePair("password", password));
 
        // getting JSON Object
        try{
        	String jsonCode = RESTClient.post(server+path, params);
			JSONObject json = new JSONObject(jsonCode);
			JSONArray jsonRelCont = json.getJSONArray("photos");
			for(int i=0; i<jsonRelCont.length(); i++){
				JSONObject data = jsonRelCont.getJSONObject(i);
				
				//create content object, which is nested into the relatedContent
				//WebPhoto p = new WebPhoto(webId, url, name, caption, location, contacts, authorName);
				WebPhoto p = new WebPhoto(
						data.getInt("id"),
						new URL(data.getString("url")), 
						data.getString("name"), 
						data.getString("caption"), 
						data.getString("location"), 
						data.getString("contacts"),
						data.getString("authorName")
						);
				res.add(p);
			}
		}
		catch (JSONException je){
			Log.e("MPM", "WebController: "+je.getMessage());
		} catch (IOException e) {
			Log.e("MPM", "WebController: "+e.getMessage());
		}
        
        return res;
    }
}
